/* Includes ------------------------------------------------------------------*/
#include "SystemTick.h"
#include "RF.h"
#include "Led.h"

/* Private typedef -----------------------------------------------------------*/
typedef void (*output_f)(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);

/* Private define ------------------------------------------------------------*/
#define LED_PRESCALE    100

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
bool s_Led_IntFlag = false;
U8   s_Led_PrescaleCnt = 0;

#define SHORT_BEEP_ON_PERIOD                (150)                  //khoang 150ms
#define SHORT_BEEP_OFF_PERIOD               (200)            //khoang 200ms
#define LONG_BEEP_ON_PERIOD                 (400)                  //khoang 300ms

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

void Led_TimerInterrupt(void)
{
    if (LED_PRESCALE <= ++s_Led_PrescaleCnt)
    {
        s_Led_PrescaleCnt = 0;
        s_Led_IntFlag = true;
    }
}


void Led_Init(void)
{
    // Initialize I/Os in Output Mode
    GPIO_Init(STATUS_LED_PORT, STATUS_LED_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);
    GPIO_Init(STATUS_BEEP_PORT, STATUS_BEEP_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);
    GPIO_Init(START_BUTTON_PORT, START_BUTTON_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);
    GPIO_Init(PAUSE_BUTTON_PORT, PAUSE_BUTTON_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);

    Led_SetOutput( STATUS_LED, true );
    Led_SetOutput( STATUS_BEEP, false );
    Led_SetOutput( START_BUTTON, true );
    Led_SetOutput( PAUSE_BUTTON, true );

    Beep_1();
    Led_SetOutput( STATUS_LED, false );

    SysTick_Registration(&Led_TimerInterrupt);
}


void Led_SetOutput( eOutput iOutput, bool iOn )
{
    output_f outputCtrl_f = ( true == iOn )? &GPIO_WriteHigh : &GPIO_WriteLow;

    switch ( iOutput )
    {
    case STATUS_LED:
        {
            outputCtrl_f( STATUS_LED_PORT, STATUS_LED_PINS );
        } break;

    case STATUS_BEEP:
        {
            outputCtrl_f( STATUS_BEEP_PORT, STATUS_BEEP_PINS );
        } break;

    case START_BUTTON:
        {
            outputCtrl_f( START_BUTTON_PORT, START_BUTTON_PINS );
        } break;

    case PAUSE_BUTTON:
        {
            outputCtrl_f( PAUSE_BUTTON_PORT, PAUSE_BUTTON_PINS );
        } break;
    } 
}


void Led_InvOutput( eOutput iOutput )
{
    switch ( iOutput )
    {
    case STATUS_LED:
        {
            Led_SetOutput( iOutput, (bool)(RESET == GPIO_ReadInputPin(STATUS_LED_PORT, STATUS_LED_PINS)) );
        } break;

    case STATUS_BEEP:
        {
            Led_SetOutput( iOutput, (bool)(RESET == GPIO_ReadInputPin(STATUS_BEEP_PORT, STATUS_BEEP_PINS)) );
        } break;

    case START_BUTTON:
        {
            Led_SetOutput( iOutput, (bool)(RESET == GPIO_ReadInputPin(START_BUTTON_PORT, START_BUTTON_PINS)) );
        } break;

    case PAUSE_BUTTON:
        {
            Led_SetOutput( iOutput, (bool)(RESET == GPIO_ReadInputPin(PAUSE_BUTTON_PORT, PAUSE_BUTTON_PINS)) );
        } break;
    } 
}


void DelayMs(U16 ms)
{
    U16 cnt;
    while(ms--)
    {
        cnt = 1200;
        while (cnt--);
    }
}


void Beep_1(void)
{
    Led_SetOutput( STATUS_BEEP, true );
    DelayMs( SHORT_BEEP_ON_PERIOD );
    Led_SetOutput( STATUS_BEEP, false );
}

void Beep_2(void)
{
    Beep_1();
    DelayMs( SHORT_BEEP_OFF_PERIOD );
    Beep_1();
}

void Beep_3(void)
{
    Beep_2();
    DelayMs( SHORT_BEEP_OFF_PERIOD );
    Beep_1();
}

void Beep_Long(void)
{
    Led_SetOutput( STATUS_BEEP, true );
    DelayMs( LONG_BEEP_ON_PERIOD );
    Led_SetOutput( STATUS_BEEP, false );
}


void Led_RunOne(void)
{
    static U8 s_Cnt = 0;
    if( NORMAL != Rf_GetMode() ) return;
    if (true == s_Led_IntFlag)
    {
        s_Led_IntFlag = false;
        ++s_Cnt;
        if (1 == s_Cnt)
        {
            Led_SetOutput( STATUS_LED, false );
        }
        else if (50 <= s_Cnt)
        {
            Led_SetOutput( STATUS_LED, true );
            s_Cnt = 0;
        }
    }
}
